// 组件内部的表达式校验工具
export interface ValidationResult {
  isValid: boolean
  error?: string
}

export interface Variable {
  name: string
  type: string
  label?: string
}

// 校验表达式
export const validateExpression = (expression: string, variables: Variable[]): ValidationResult => {
  if (!expression || !expression.trim()) {
    return { isValid: false, error: '表达式不能为空' }
  }

  // 基本语法检查
  const syntaxErrors = checkSyntaxErrors(expression)
  if (syntaxErrors.length > 0) {
    return { isValid: false, error: syntaxErrors[0] }
  }

  // 检查变量是否存在
  const usedVariables = extractVariables(expression)
  const availableVarNames = variables.map(v => v.name)
  
  for (const varName of usedVariables) {
    if (!availableVarNames.includes(varName)) {
      return { isValid: false, error: `未定义的变量: ${varName}` }
    }
  }

  return { isValid: true }
}

// 检查语法错误
const checkSyntaxErrors = (expression: string): string[] => {
  const errors: string[] = []
  
  // 检查括号匹配
  let parenthesesCount = 0
  let inQuotes = false
  let quoteChar = ''
  
  for (let i = 0; i < expression.length; i++) {
    const char = expression[i]
    
    if ((char === '"' || char === "'") && !inQuotes) {
      inQuotes = true
      quoteChar = char
    } else if (char === quoteChar && inQuotes) {
      inQuotes = false
      quoteChar = ''
    } else if (!inQuotes) {
      if (char === '(') {
        parenthesesCount++
      } else if (char === ')') {
        parenthesesCount--
        if (parenthesesCount < 0) {
          errors.push('括号不匹配：多余的右括号')
          break
        }
      }
    }
  }
  
  if (parenthesesCount > 0) {
    errors.push('括号不匹配：缺少右括号')
  }
  
  if (inQuotes) {
    errors.push('引号不匹配：缺少结束引号')
  }
  
  // 检查操作符
  // const invalidOperators = /[^a-zA-Z0-9_\s\(\)\+\-\*\/\=\!\<\>\&\|\"\'\.]/g
  // const matches = expression.match(invalidOperators)
  // if (matches) {
  //   errors.push(`包含无效字符: ${matches.join(', ')}`)
  // }
  
  return errors
}

// 提取表达式中的变量
const extractVariables = (expression: string): string[] => {
  const variables: string[] = []
  let inQuotes = false
  let quoteChar = ''
  let currentToken = ''
  
  for (let i = 0; i < expression.length; i++) {
    const char = expression[i]
    const prevChar = i > 0 ? expression[i - 1] : ''
    
    // 处理引号
    if ((char === '"' || char === "'") && prevChar !== '\\') {
      if (!inQuotes) {
        inQuotes = true
        quoteChar = char
        // 如果当前有token，先处理它
        if (currentToken) {
          processToken(currentToken, variables)
          currentToken = ''
        }
      } else if (char === quoteChar) {
        inQuotes = false
        quoteChar = ''
      }
      continue
    }
    
    // 在引号内，跳过所有字符
    if (inQuotes) {
      continue
    }
    
    // 处理标识符字符
    if (/[a-zA-Z_]/.test(char) || (currentToken && /[a-zA-Z0-9_]/.test(char))) {
      currentToken += char
    } else {
      // 遇到分隔符，处理当前token
      if (currentToken) {
        processToken(currentToken, variables)
        currentToken = ''
      }
    }
  }
  
  // 处理最后一个token
  if (currentToken && !inQuotes) {
    processToken(currentToken, variables)
  }
  
  return [...new Set(variables)]
}

// 处理单个token，判断是否为变量
const processToken = (token: string, variables: string[]) => {
  // 过滤掉关键字、函数名和纯数字
  const keywords = ['and', 'or', 'not', 'true', 'false', 'null', 'if', 'else', 'in', 'contains']
  
  // 检查是否为纯数字
  if (/^\d+(\.\d+)?$/.test(token)) {
    return
  }
  
  // 检查是否为关键字
  if (keywords.includes(token.toLowerCase())) {
    return
  }
  
  // 检查是否为有效的变量名（以字母或下划线开头）
  if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(token)) {
    variables.push(token)
  }
}

// 格式化表达式
export const formatExpression = (expression: string): string => {
  return expression
    .replace(/\s+/g, ' ')
    .replace(/\s*([()=!<>+\-*/])+\s*/g, ' $1 ')
    .replace(/\s+/g, ' ')
    .trim()
}

// 获取表达式建议
export const getExpressionSuggestions = (expression: string, variables: Variable[]): string[] => {
  const suggestions: string[] = []
  
  // 基本操作符建议
  const operators = ['==', '!=', '>', '<', '>=', '<=', 'and', 'or', 'not', 'in', 'contains']
  suggestions.push(...operators)
  
  // 变量建议
  variables.forEach(variable => {
    suggestions.push(variable.name)
    if (variable.label && variable.label !== variable.name) {
      suggestions.push(`${variable.name} // ${variable.label}`)
    }
  })
  
  return suggestions
}